// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;

namespace SnapObjects.Expressions
{
    internal class DefaultEvaluateMethodProvider : MetadataProvider<EvaluateResult>
    {
        private readonly EvaluateMethodMetaParser _methodMetaParser;
        private readonly CacheCollection<Type, IDictionary<string, EvaluateMethodMetadata>> _types;

        public DefaultEvaluateMethodProvider(IServiceProvider services)
        {
            _methodMetaParser = new EvaluateMethodMetaParser();

            _types = new CacheCollection<Type, IDictionary<string, EvaluateMethodMetadata>>(
                services.GetService<ICacheProvider>(), CacheSourceKind.EVALUATE_METHODS, x => x.FullName);
        }

        public override MetadataType Type => MetadataType.Method;

        public override bool TryGet(
            object key, ParserOptions<EvaluateResult> options, out Metadata<EvaluateResult> metadata)
        {
            var name = (string)key;

            if (String.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            var type = options.DataSource.GetType();

            var methods = _types.GetOrSet(
                type, () => _methodMetaParser.GetMethodMeta(type));

            if (methods.TryGetValue(name, out var value))
            {
                metadata = value;

                return true;
            }

            metadata = null;

            return false;
        }
    }
}
